package com.util;

import org.junit.Test;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

/**
 * https://yemengying.com/2016/05/07/threadsafe-hashmap/
 * Created by yangliwei on 2017/7/29.
 */
public class HashMapDemo {
    /**
     * 将map转化为线程安全的
     */
    @Test
    public void convertSyncMap(){
        HashMap map =new HashMap();
        map.put("测试","使map变成有序Map");
        Map map1 = Collections.synchronizedMap(map);
    }

    @Test
    public void testConstruct() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        System.out.println();
        //这里面的调试，因为刚刚开始HashMap也被java内部的类使用，所以断点会奇奇怪怪的，hashmap的容量必须为2的次方，与hash算法后取模有关
        HashMap hashMap = new HashMap(12,0.8f);

        Class<?> mapType = hashMap.getClass();
        Method capacity = mapType.getDeclaredMethod("capacity");
        capacity.setAccessible(true);
        System.out.println("capacity : " + capacity.invoke(hashMap));

    }


    @Test
    public void testGet(){
        //map 当key为null时，可以取到值
        Map<String,String> map = new HashMap();
        String key = null;
        String result = map.get(key);
        System.out.println(result);
        map.put(key, "key is null");
        System.out.println(map.get(key));


    }

    /**
     * 一个default方法，用来返回当前数字最接近的2的指数次
     * static final int tableSizeFor(int cap)
     * 如 ：
     *  2 ->2
     *  3->4
     *  11->16
     *  主要使用了无符号位运算
     */
    @Test
    public void testTableSizeFor(){
//        10000100001000    -1
//        10000100000111    >>>1
//         1000010000011    |
//        11000110000111    >>>2
//          110001100001    |
//        11110111100111    >>>4
//            1111011110    |
//        11111111111111    你敢信，特么变成了都是111111了
        int n = 1;
        n -=1;
        n |= n >>> 1;
        n |= n >>> 2;
        n |= n >>> 4;
        n |= n >>> 8;
        n |= n >>> 16;
        n+=1;
        System.out.println(n);
    }

    @Test
    public void testContainValue(){
        Map map = new HashMap();
        map.put("1", "a");
        map.put("2", "b");
        System.out.println(map.containsValue("a"));
        System.out.println(map.containsValue("1"));
    }

//    @Test
//    public void test01(){
//        HashMap tree = new HashMap();
//        tree.forEach((key,value)-> Optional.ofNullable(value).filter(value ->"aa".equals(value)).map(t->tree.get(value.hashCode())).isPresent());
//    }
}
